/*
    monopoly.js:

*/

if (typeof GAME == "undefined") {
    GAME = {//creating the game varible
	version: "1.0.5",
	build: 1
    };
}

GAME.AJAX_URL = "MonopolyServlet"; // URL of Ajax call//adding property
GAME.ACTION = {
    GET_STATE:  "state",
    ASSSET_BUY_ANSWER: "asset",
    HOUSE_BUY_ANSWER: "house",
    CLIENT_DICES: "dices",
    RESIGN_ANSWER: "quit"
};

GAME.UPDATE_INTERVAL = 650; // how often we check for state update (in milisec)
GAME.MAX_PLAYERS = 6; // support 2 to 6 players
GAME.MOVEMENT_DONE = "movementdone"; // event movementdone is fiered after all anomations are done

// create a private scope and map $ to jQuery
(function($){

    // Player object
    GAME.Player = function(id){
	this.id = id;
	this.cell = 1;
	this.element = $("<li id='player" + this.id + "' class='player-elem hidden player-icon'> </li>")
	this.element.appendTo($("#playersList"));

    };
    //reset visual presentation
    GAME.Player.prototype.reset = function(){
	var assetClassName = "player" + this.id + "-asset";//creasting class
	// remove assets
	$("#playerAsset").empty();//objects in list
	$("#playerCards").empty();//objects in list
	$("." + assetClassName).removeClass(assetClassName).removeClass("house3").removeClass("house2").removeClass("house1");
    };

    // update the Player state
    GAME.Player.prototype.update = function(oState){
	var Player = this,
	position,
	parkingCount,
	targetCell,
	unregister = function(){
	    GAME.monopoly.registerAmimation(-1);
	};

	$.each(oState.assets, function(){
	    $("#cell" + this.address).addClass("player" + Player.id + "-asset");
	    if (this.houses){
		$("#cell" + this.address).addClass("house" + this.houses);
	    }
	});

	var boardPosition = oState.location;
	var previousCell = this.cell;

	// is there someone allready parked on our cell? if so, add a small offset
	occupiedCellsMap = GAME.monopoly.getOccupiedCellsMap ();
	parkingCount = occupiedCellsMap[boardPosition] ? occupiedCellsMap[boardPosition] : 0;

	var previousParkingCount = occupiedCellsMap[previousCell] ? occupiedCellsMap[previousCell] : 0;
	occupiedCellsMap[previousCell] = previousParkingCount - 1;

	occupiedCellsMap[boardPosition] = parkingCount + 1;
	targetCell =  $("#cell" + boardPosition);
	position  = targetCell.position();
	this.element.css({
	    top: position.top + (targetCell.height() / 3),
	    left: position.left + (targetCell.width() / 2) + (parkingCount * 10) - 20
	});

	if(this.cell !== oState.location){
	    updateLegend(oState);
	    GAME.monopoly.registerAmimation(1);
	    while (this.cell !== oState.location){
		this.cell = this.cell % 36 + 1;
		targetCell =  $("#cell" + this.cell);
		position  = targetCell.position();
		this.element.animate({
		    top: position.top + (targetCell.height() / 3),
		    left: position.left + (targetCell.width() / 3) + (parkingCount * 10) - 20
		},
		200,  this.cell === oState.location ? unregister : $.noop);
	    }
	}
	this.cell = boardPosition;

	// if other players are on the same cell
	if (previousParkingCount > 1)
	{
	    // re-organize the players on the previous cell
	    var i;
	    var counter = 0;
	    var previousCellElement = $("#cell" + previousCell);
	    var previousPosition = previousCellElement.position();
	    for (i = 0; i < GAME.MAX_PLAYERS; i++)
	    {
		if (GAME.monopoly.getPlayers()[i])
		{
		    if (GAME.monopoly.getPlayers()[i].cell == previousCell)
		    {
			GAME.monopoly.getPlayers()[i].element.css({
			    top: previousPosition.top + (previousCellElement.height() / 3),
			    left: previousPosition.left + (previousCellElement.width() / 2) + (counter * 10) - 20
			});
			counter = counter + 1;
		    }
		}
	    }
	}

	Player.element.attr('title', oState.name);
	Player.element.removeClass("hidden");
    };

    GAME.Player.prototype.legend = function(oState, legend){
	$("#playerName").text(oState.name);
	$("#playerCash").text(oState.funds);
	$("#playerCashText").text("in " + oState.name + "'s bank");
	$("#playerColor").removeClass().addClass("player"+oState.id);

	try{
	    $.each(oState.assets,function(index, value){
		$("<li>" + value.name + "</li>").appendTo("#playerAsset");
	    });
	}
	catch(e){
	    alert(e);
	}

	try{
	    if(typeof(oState.prisoncard) != "undefined"){
		$("<li>Get Out Of Prison</li>").appendTo("#playerCards");
	    }
	}catch(e){
	    alert(e);
	}

    };

}(jQuery));

// make sure the $ is maped to the jQuery function at least inside our function

GAME.monopoly = function($){
    var players = [], // hold reference to all players
    occupiedCellsMap = [], // which cells are occupied - to calculate position in cell
    legend,
    notify,//new added by avia
    question_dialog,
    dices_dialog,
    resign_dialog,
    pendingAjaxCall,
    pendingAnimations = 0;

    // updatePlayer
    updatePlayer = function(n, Player){
	players[Player.id-1].update(Player);
    },

    // updateLegend
    updateLegend = function(Player){
	players[Player.id-1].legend(Player, legend);
    },

    // display the dialog that was passed
    showDialog = function(dialogWrap, isOn){
	var collapsedWidth = 150,
	collapsedHeight = 200,
	targetTop,
	targetLeft,
	targetWidth,
	targetHeight,
	targetOpacity;

	if (isOn){
	    dialogWrap.css({
		opacity: 'hide',
		position: 'absolute',
		top: ($(window).height() - collapsedHeight) / 2,
		left:($(window).width() - collapsedWidth) / 2,
		width: collapsedWidth
	    //		height: collapsedHeight
	    });
	    targetWidth =  530;
	    targetHeight =  $(window).height() / 3;
	    targetTop =  $(window).height() / 4;
	    targetLeft =  $(window).width() / 4;
	    targetOpacity = 1;
	} else {
	    targetWidth =  collapsedWidth;
	    targetHeight = collapsedHeight;
	    targetTop = ($(window).height() - collapsedHeight) / 2;
	    targetLeft = ($(window).width() - collapsedWidth) / 2;
	    targetOpacity = 0;
	}

	dialogWrap.removeClass("hidden")
	.animate(
	{
	    opacity: targetOpacity,
	    width: targetWidth,
	    //	    height: targetHeight,
	    top: targetTop,
	    left: targetLeft
	},
	200,
	function(){
	    if (!isOn)
	    {
		dialogWrap.addClass("hidden");
	    }
	    else
		dialogWrap.removeClass("hidden");
	}
	);

    },

    askresign = function(){
	showDialog(resign_dialog,true);
    },

    //display a dialog and ask a question
    ask = function(quest){
	question_dialog.find(".question").text(quest.question).end()
	.find("#buyAction").val(quest.id).end()
	.find("#state-flag").attr("src","img/state_flags/"+quest.state.toString().toLowerCase().replace(" ", "_")+".png").end()
	.find("#asset-state").text(quest.state).end()
	.find("#asset-details").html(quest.details).end()
	.find("#btn1").text(quest.option1).end()
	.find("#btn2").text(quest.option2).end();
	showDialog(question_dialog, true);
    },

    //display a throw dices dialog
    throwDices = function(){
	dices_dialog.find("#cube1").val("").end().find("#cube2").val("").end();
	showDialog(dices_dialog, true);
    },

    _registerAmimation = function(i){
	pendingAnimations += i;
	if (i < 0 && pendingAnimations === 0){
	    $("#monopoly-frame").trigger(GAME.MOVEMENT_DONE);
	}
    },

    // handle server update
    handleServerUpdate = function(o){
	var i;
	var PLAYER_NAME;
	var LAST_NOFIY;

	PLAYER_NAME = $("#currPlayerName").val();
	LAST_NOFIY = $("#lastNotification").val();
	//console.log("ver " + o.ver);
	pendingAjaxCall = null;
	pendingAnimations = 1;


	if(o != null){
	    try{
		if(o.cashier){
		    $("#bank-cash-txt").text(o.cashier);
		}

		// Save the Dices
		var dice1, dice2;
		dice1 = $("#dice1").val();
		dice2 = $("#dice2").val();
		if(o.cubes != "undefined"){
		    $("#dice1").css({
			'background-image': 'url(img/cubes/' + o.cubes.cube1+ 'cube.png)'
		    });
		    $("#dice2").css({
			'background-image': 'url(img/cubes/' + o.cubes.cube2+ 'cube.png)'
		    });
		}
	    }catch(e) {
		alert(e)
		$("#dice1").val(dice1);
		$("#dice2").val(dice2);
	    }

	    try{
		// reset previous state
		occupiedCellsMap = [];
		for (i = 0; i < GAME.MAX_PLAYERS; i++){
		    players[i].reset();
		}

		if(o.players != "undefined"){
		    // render the new state
		    $.each(o.players, updatePlayer);
		}
	    }catch(e){
		alert(e);
		if(o == null){
		    alert("The Game is Over! Redirecting to The Start Page");
		    $.post(
			GAME.AJAX_URL,
			$.param({
			    action: "redirect"
			})
			);
		}
	    }

	    // Show any messages
	    try{
		if(typeof(o.notification) != "undefined"){
		    if(o.notification.message !== LAST_NOFIY){
			alert(o.notification.message)
			$("#lastNotification").val(o.notification.message);
		    }
		}
	    }catch(e){}

	    try{
		// register for a "one time" event
		$("#monopoly-frame").one(GAME.MOVEMENT_DONE , function(){
		    if (typeof(o.questDialog) != "undefined"){
			if(o.questDialog.playerName == PLAYER_NAME ){
			    ask(o.questDialog);
			}
		    } else if (typeof(o.dicesDialog) != "undefined"){
			if(o.dicesDialog.playerName == PLAYER_NAME ){
			    throwDices();
			}
		    } else {
			setTimeout(updateState, GAME.UPDATE_INTERVAL);
		    }
		});
	    }catch(e){
		alert(e)
	    }
	}
	_registerAmimation(-1);
    },
         
    // ask server for updates
    updateState = function(){
	pendingAjaxCall = $.getJSON(
	    GAME.AJAX_URL,
	    "action=" + GAME.ACTION.GET_STATE,
	    handleServerUpdate
	    );
    };

    postBuyReply = function(answerToSend) {
	return function() {
	    var answerAction = $("#buyAction").val();
	    $.post(
		GAME.AJAX_URL,
		$.param({
		    answer: answerToSend,
		    action: answerAction
		})
		);
	    showDialog(question_dialog, false);
	    setTimeout(updateState, GAME.UPDATE_INTERVAL + 500);
	}
    };
    //postdicereply
    postCubesThrow = function(cube1Val, cube2Val){
	return function(){
	    $.post(
		GAME.AJAX_URL,
		$.param({
		    action: GAME.ACTION.CLIENT_DICES,
		    cube1: $("#cube1").val(),
		    cube2: $("#cube2").val()
		}),
		handleServerUpdate);
	    showDialog(dices_dialog, false);
	    $("#dice1").css({
		'background-image': 'url(img/cubes/' +cube1Val+ 'cube.png)'
	    });
	    $("#dice2").css({
		'background-image': 'url(img/cubes/' +cube2Val+ 'cube.png)'
	    });
	}
    };

    //post resignreply
    postResignReply = function(answerToSend){
	return function(){
	    if(answerToSend === "yes"){
		$.post(
		    GAME.AJAX_URL,
		    $.param({
			action: GAME.ACTION.RESIGN_ANSWER,
			answer: answerToSend
		    }),
		    handleServerUpdate);
	    }
	    showDialog(resign_dialog, false);
	    setTimeout(updateState,  GAME.UPDATE_INTERVAL + 500);
	}
    };

    return {
	init:function(){
	    var i;
            
	    var resignButton = $('<div id="resign"><button id="leave" class="click-button">Resign</button></div>');
	    resignButton.appendTo($("#monopoly-frame"));
	    $("#leave").click(function()
	    {
		askresign();
	    });

	    var dicePanel = $('<div id="dice1" class="diceFrame"/><div id="dice2" class="diceFrame"/>');
	    dicePanel.appendTo($("#monopoly-frame"));

	    // create a dialog for later server questions
	    question_dialog = $("<div id='questDialog' class='dialog-back hidden'>"
		+"<h3 class='dialog-question question'>Would you like to Buy:</h3>"
		+"<div class='dialog-asset-name'>"
		+"<img class='flag-icon' id='state-flag' src='img/smielly.jpg'>"
		+"<h2 class='dialog-h2-title' id='asset-state'></h2>"
		+"<span class='dialog-mini-title' id='asset-details'></span>"
		+"</div>"
		+"<div class='dialog-asset-name2'>"
		+"<button id='btn1' class='dialog-button'>option1</a>"
		+"<button id='btn2' class='dialog-button'>option2</a>"
		+"</div>"
		+"<div style='clear:both;'></div>"
		+"<input id='buyAction' type='hidden'/>"
		+"</div>");
	    question_dialog.appendTo($("#monopoly-frame"));
	    $("#btn1").click(postBuyReply("yes"));
	    $("#btn2").click(postBuyReply("no"));

	    // create a dialog for manual dices input
	    dices_dialog = $("<div id='dicesDialog' class='dialog-back hidden'>"
		+"      <h3 class='dialog-question question'>Please throw the dices</h3>"
		+"      <div class='dialog-mini-title'>"
		+"              <span class='dialog-h2-title'>Cube 1:</span><input type='text' id='cube1' />"
		+"              <span class='dialog-h2-title'>Cube 2:</span><input type='text' id='cube2' />"
		+"      </div>"
		+"      <div class='dialog-asset-name2'>"
		+"                      <button id='btnThrow' class='dialog-button'>OK</button>"
		+"              </div>  "
		+"              <div style='clear:both;'></div>"
		+"</div>                  ");
	    dices_dialog.appendTo($("#monopoly-frame"));
	    $("#btnThrow").click(postCubesThrow());

	    // Create the Resign Dialog
	    resign_dialog = $("<div id='resignDialog' class='dialog-back hidden'>"
		+ "	<h3 class='dialog-question'>Are you sure you want to Quit the game?</h3>"
		+ "	<div class='dialog-question'>"
		+ "	<center>"
		+ "		<button id='btnResYes' class='dialog-button'>Yes</button>"
		+ "		<button id='btnResNo' class='dialog-button'>No</button>"
		+ "		</center>"
		+ "	</div>"
		+ "	<div style='clear:both;'></div>"
		+ "</div>");
	    resign_dialog.appendTo($("#monopoly-frame"));
	    $("#btnResYes").click(postResignReply("yes"));
	    $("#btnResNo").click(postResignReply("no"));

	    // build players array
	    for (i = 1; i <= GAME.MAX_PLAYERS; i++){
		players[i-1] = new GAME.Player(i);
	    }

	    $.ajaxSetup ({
		// Disable caching of AJAX responses
		cache: false,
		// Disable AJAX Asynchronius Calls
		async: false
	    });
            
	    // start checking for state update
	    updateState();
	},

	registerAmimation: function(i){
	    _registerAmimation(i);
	},

	getOccupiedCellsMap : function() {
	    return occupiedCellsMap;
	}

    };

}(jQuery);

// on document ready - call init
jQuery(GAME.monopoly.init);



















